import { inject, createVNode, defineComponent, reactive, render, computed, ref, onMounted, onBeforeUnmount, toRefs, provide } from "vue";

export const DropdownItem = defineComponent({
  props:{
    label: String,
    icon: String,
  },
  setup(props, ctx) {
    let {label, icon} = toRefs(props)

    let hide = inject('hide')
    return () => <div class="dropdown-item" onClick={hide}>
      <i class={icon.value}></i>
      <span>{label.value}</span>
    </div>
  }
})


const DropdownComponent = defineComponent({
  props: {
    options: {type: Object},
  },
  setup(props, ctx) {
    const state = reactive({
      options: props.options,
      isShow: false,
      top:0,
      left: 0
    })
    // 对外 暴露方法
    ctx.expose({
      showDropDown(options) {
        state.options = options
        state.isShow = true
        let {top, left, height} = options.el.getBoundingClientRect()
        state.top = top + height
        state.left = left
      }
    })

    provide('hide', () => {
      state.isShow = false
    })

    const styles = computed(() => ({
      top: state.top + 'px',
      left: state.left + 'px'
    }))
    const classes = computed(() => [
      'dropdown',
      {
        'dropdown-isShow': state.isShow
      }
    ])

    const el = ref(null)

    const onMousedownDocument = (e) => {
      // 点击的是内部
      if (!el.value.contains(e.target)) {
        state.isShow = false
      }
    }

    onMounted(() => {
      // 元素的点击禁止了 冒泡，所以这里采用 捕获
      document.addEventListener('mousedown', onMousedownDocument, true)
    })

    onBeforeUnmount(() => {
      document.removeEventListener('mousedown', onMousedownDocument)
    })

    // class 和 className
    return () => {
      return <div class={classes.value} style={styles.value} ref={el}>
        {state.options.content()}
      </div>
    }
  }
})

let vm
export function $dropdown(options) {
  if (!vm) {
    // new SubComponent.$mount()
    let el = document.createElement('div')

    // 组件  渲染  虚拟节点
    vm = createVNode(DropdownComponent, {options})
    render(vm, el)// 虚拟节点变为真节点  返回的是 undefined
    document.body.appendChild(el)
  }
  // 将组建渲染到 el 元素上

  let {showDropDown} = vm.component.exposed
  showDropDown(options)
}